home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
misc
/
emu
/
AmigaVGB.lha
/
AmigaVGB
/
Amiga.c
next >
Wrap
C/C++ Source or Header
|
1996-09-23
|
11KB
|
421 lines
/** VGB: portable GameBoy emulator ***************************/
/** **/
/** Amiga.c **/
/** **/
/** Amiga-specific graphics/joystick routines drivers. **/
/** **/
/** Copyright (C) Lars Malmborg 1996 **/
/** based on a version by Michael Boese & Matthias Bethke **/
/** and the Unix/X version. **/
/** **/
/** Copyright (C) Marat Fayzullin 1994,1995,1996 **/
/** Elan Feingold 1995 **/
/** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/
/** changes to this file. **/
/*************************************************************/
#define REVISION "rev. 2"
#define USE_XPAL /* We are using XPal[] to determine colors */
/* Amiga includes */
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/asl.h>
#include <dos/rdargs.h>
#include <exec/memory.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#ifdef CYBER
#include <proto/cybergraphics.h>
#include <cybergraphics/cybergraphics.h>
#endif
void __inline AllocatePens(void);
#include "GB.h"
#include "AmigaRawkeys.h"
/** Various variables and short functions ********************/
#define WIDTH_OFFS 8
#define WIDTH (160+2*WIDTH_OFFS)
#define HEIGHT 144
char *Title = "Virtual GameBoy 0.7";
char *AmigaVersion="$VER: Virtual GameBoy Amiga 0.7 "REVISION" "__AMIGADATE__;
int ExitFlag = 0;
byte *XBuf=NULL,*ZBuf=NULL;
LONG XPal[12]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
struct Screen *scr=NULL;
struct Window *win=NULL;
struct RastPort *rp=NULL;
char ReqText[]= "Virtual Gameboy V0.7 by\n\
Marat Fayzullin <fms@freeflight.com>\n\
Amiga version "REVISION" "__AMIGADATE__" by\n\
Lars Malmborg <glue@df.lth.se>\n\n\
In-game keys:\n\
Left Alt or '+' on key pad - 'A'\n\
Left Shift or '6' on key pad - 'B'\n\
Right Shift or '4' on key pad - 'Select'\n\
Return or '5' on key pad - 'Start'\n\
Cursorkeys - Joypad\n\n\
ESC - Quit emulation\n"
#ifdef DEBUG
"\
F1 - Go into built-in debugger\n\
F2 - Show LCD controller registers\n"
F3 - Show sprite registers\n"
#endif
; //Gremlins!
struct EasyStruct HelpReq =
{
sizeof(struct EasyStruct),
0,
"VGB Amiga Help",
ReqText,
"OK"
};
#ifndef CYBER
struct RastPort temprp;
/*
struct BitMap tempbm;
char tempp[WIDTH*8];
*/
#endif
BOOL ScaleUp;
STRPTR PubScreen;
int InitMachine(void)
{
int scale;
if (ScaleUp)
scale=2;
else
scale=1;
if (scr = LockPubScreen(PubScreen))
{
if(win = OpenWindowTags(NULL,
WA_Left,(scr->Width - scale*(WIDTH-2*WIDTH_OFFS))/2,
WA_Top,(scr->Height - scale*HEIGHT)/2,
WA_InnerWidth,scale*(WIDTH-2*WIDTH_OFFS),
WA_InnerHeight,scale*HEIGHT,
WA_Title,Title,
WA_CloseGadget,TRUE,
WA_DepthGadget,TRUE,
WA_DragBar,TRUE,
WA_SizeGadget,FALSE,
WA_RMBTrap,TRUE,
WA_Activate,TRUE,
WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW,
WA_PubScreenName,PubScreen,
TAG_END
))
{
UnlockPubScreen(PubScreen,scr);
rp = win->RPort;
AllocatePens();
if(!(XBuf=AllocVec(sizeof(byte)*HEIGHT*WIDTH,MEMF_ANY))) return(0);
if(!(ZBuf=AllocVec(sizeof(byte)*2*WIDTH*HEIGHT/8,MEMF_ANY))) return(0);
#ifndef CYBER
// init temprp
CopyMem(rp,&temprp,sizeof(struct RastPort));
temprp.Layer=NULL;
if (!(temprp.BitMap=AllocBitMap(scale*(WIDTH-2*WIDTH_OFFS),1,rp->BitMap->Depth,0,NULL)))
{
fprintf(stderr,"Error allocating temporary rastport.\n");
return(0);
}
#endif
}
else
{
fprintf(stderr,"Can't open window.\n");
return(0);
}
}
else
{
fprintf(stderr,"Screen not found.\n");
return(0);
}
return(1);
}
/** TrashMachine *********************************************/
/** Deallocate all resources taken by InitMachine(). **/
/*************************************************************/
void TrashMachine(void)
{
int i;
#ifndef CYBER
// release temprp
if (temprp.BitMap)
FreeBitMap(temprp.BitMap);
#endif
if (ZBuf)
FreeVec(ZBuf);
if (XBuf)
FreeVec(XBuf);
if (win)
CloseWindow(win);
for(i=0; i<12; i++)
if (XPal[i]!=-1)
ReleasePen(scr->ViewPort.ColorMap,XPal[i]);
}
/** PutImage *************************************************/
/** Put an image on the screen. **/
/*************************************************************/
void PutImage(void)
{
#ifdef CYBER
// Render with cybergraphics.library
int scale;
if (ScaleUp)
scale=2;
else
scale=1;
WritePixelArray(XBuf,WIDTH_OFFS,0,scale*WIDTH,rp,win->BorderLeft,win->BorderTop,scale*(WIDTH-2*WIDTH_OFFS),HEIGHT,RECTFMT_LUT8);
#else
// Render with graphics.library
if (ScaleUp)
{
register int i;
for(i=0;i<144;i++)
{
UBYTE drawarray[2*(WIDTH-2*WIDTH_OFFS)];
register int n;
for (n=0;n<(WIDTH-2*WIDTH_OFFS);n++)
{
drawarray[n*2]=(UBYTE)(XBuf[(i*WIDTH)+n+WIDTH_OFFS]);
drawarray[n*2+1]=drawarray[n*2];
}
WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i*2,2*(WIDTH-2*WIDTH_OFFS),drawarray,&temprp);
WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i*2+1,2*(WIDTH-2*WIDTH_OFFS),drawarray,&temprp);
}
}
else
{
register int i;
for(i=0;i<144;i++)
{
WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i,WIDTH-2*WIDTH_OFFS,(UBYTE*)(&XBuf[(i*WIDTH)+WIDTH_OFFS]),&temprp);
}
}
}
/** Joystick *************************************************/
/** Return the current joystick state. **/
/*************************************************************/
byte Joystick(void)
{
struct IntuiMessage *imsg;
ULONG imsg_Class;
UWORD Code;
#ifdef DEBUG
int J;
#endif
static byte JoyState=0xff;
if(imsg = (struct IntuiMessage*)GetMsg(win->UserPort))
{
imsg_Class = imsg->Class;
Code = imsg->Code;
ReplyMsg((struct Message*)imsg);
switch(imsg_Class)
{
case IDCMP_CLOSEWINDOW:
ExitFlag = 1;
break;
case IDCMP_RAWKEY:
if(Code & 0x80)
{
switch(Code & 0x7f)
{
#ifdef DEBUG
case KEY_F1:
Trace=!Trace;
break;
case KEY_F2:
puts("\n*** REGISTERS: ***"); //F2 up
for(J=0xFF40;J<0xFF50;J++)
printf("(%Xh) = %Xh\n",J,RAM[J]);
printf("ISWITCH = %Xh\n",ISWITCH);
break;
case KEY_F3:
puts("\n*** SPRITES: ***");
for(J=0xFE9C;J<0xFE9C+4*40;J+=4)
printf("SPRITE %d: %d,%d Pat %d Attr %d\n",(J-0xFE9C)/4,RAM[J+1],RAM[J],RAM[J+2],RAM[J+3]);
break;
#endif
case KEY_HELP:
EasyRequestArgs(win,&HelpReq,NULL,NULL);
break;
case KEY_RETURN: //start
case KEY_P5:
JoyState|=0x80;
break;
case KEY_RSHIFT: //select
case KEY_P4:
JoyState|=0x40;
break;
case KEY_LSHIFT: //B
case KEY_P6:
JoyState|=0x20;
break;
case KEY_LALT: //A
case KEY_PPLUS:
JoyState|=0x10;
break;
case KEY_CDOWN: //Down
JoyState|=0x08;
break;
case KEY_CUP: //Up
JoyState|=0x04;
break;
case KEY_CLEFT: //Left
JoyState|=0x02;
break;
case KEY_CRIGHT: //Right
JoyState|=0x01;
break;
}
}
else
{
switch(Code)
{
case KEY_ESC:
ExitFlag = 1;
break;
case KEY_RETURN:
case KEY_P5:
JoyState&=0x7F;
break;
case KEY_RSHIFT:
case KEY_P4:
JoyState&=0xBF;
break;
case KEY_LSHIFT:
case KEY_P6:
JoyState&=0xDF;
break;
case KEY_LALT:
case KEY_PPLUS:
JoyState&=0xEF;
break;
case KEY_CDOWN:
JoyState&=0xF7;
break;
case KEY_CUP:
JoyState&=0xFB;
break;
case KEY_CLEFT:
JoyState&=0xFD;
break;
case KEY_CRIGHT:
JoyState&=0xFE;
break;
}
}
break;
}
}
if(ExitFlag)
{ TrashGB();TrashMachine();exit(0); }
return(JoyState);
}
struct
{
LONG r,g,b;
} GB_Colors[12]={
{0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
{0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000},
{0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
{0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000},
{0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
{0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000}};
void SetColors(int mode, char* color)
{
long tcol[4];
int i=0;
while (!isdigit(color[i])) i++;
sscanf(color,"%lx,%lx,%lx,%lx",&tcol[0],&tcol[1],&tcol[2],&tcol[3]);
GB_Colors[mode+0].r=(tcol[0]&0x00ff0000)<<8;
GB_Colors[mode+0].g=(tcol[0]&0x0000ff00)<<16;
GB_Colors[mode+0].b=(tcol[0]&0x000000ff)<<24;
GB_Colors[mode+1].r=(tcol[1]&0x00ff0000)<<8;
GB_Colors[mode+1].g=(tcol[1]&0x0000ff00)<<16;
GB_Colors[mode+1].b=(tcol[1]&0x000000ff)<<24;
GB_Colors[mode+2].r=(tcol[2]&0x00ff0000)<<8;
GB_Colors[mode+2].g=(tcol[2]&0x0000ff00)<<16;
GB_Colors[mode+2].b=(tcol[2]&0x000000ff)<<24;
GB_Colors[mode+3].r=(tcol[3]&0x00ff0000)<<8;
GB_Colors[mode+3].g=(tcol[3]&0x0000ff00)<<16;
GB_Colors[mode+3].b=(tcol[3]&0x000000ff)<<24;
}
void AllocatePens(void)
{
int i;
for(i=0; i<12; i++)
{
XPal[i] = ObtainBestPenA(scr->ViewPort.ColorMap,GB_Colors[i].r,GB_Colors[i].g,GB_Colors[i].b,NULL);
}
}
/*** SIOSend ****************************************************/
/*** Send a byte onto the serial line. ***/
/****************************************************************/
byte SIOSend(register byte V) { return(0); }
/*** SIOReceive *************************************************/
/*** Receive a byte from the serial line. Returns 1 on ***/
/*** success, 0 otherwise. ***/
/****************************************************************/
byte SIOReceive(register byte *V) { return(0); }
/****************************************************************/
/*** Write value into sound chip register (Reg #0 at FF10h). ***/
/****************************************************************/
void Sound(byte R,byte V) { return; }
/** Common.h ****************************************************/
/** Parts of the drivers common for Unix/X and MSDOS. **/
/****************************************************************/
#include "Common.h"